package spider

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"io"
	"reflect"
	"regexp"
	"strings"
)

type Movie struct {
	SubjectID    string `sql:"subject_id"`
	Name         string `sql:"name"`
	Director     string `sql:"director"`
	Starring     string `sql:"starring"`
	Style        string `sql:"style"`
	Area         string `sql:"area"`
	Language     string `sql:"language"`
	ReleaseDate  string `sql:"release_date"`
	Len          string `sql:"len"`
	Alias        string `sql:"alias"`
	Description  string `sql:"description"`
	Score        string `sql:"score"`
	EvaluateNums string `sql:"evaluate_nums"`
	Link         string `sql:"link"`
}

func GetSearchList(str string) []string {
	subjectIDRegexp := regexp.MustCompile(`"id":"(\d+)"`)
	params := subjectIDRegexp.FindAllStringSubmatch(str, -1)
	ids := []string{}
	for _, item := range params {
		ids = append(ids, item[1])
	}
	return ids
}

func GetMovieList(html io.Reader) []string {
	links := []string{}
	doc, err := goquery.NewDocumentFromReader(html)
	if err != nil {
		return links
	}
	subjectIDRegexp := regexp.MustCompile(`^https://movie.douban.com/subject/(\d+)/$`)
	doc.Find("#content .grid_view .item .hd > a").Each(func(i int, s *goquery.Selection) {
		res, ok := s.Attr("href")
		if ok {
			params := subjectIDRegexp.FindStringSubmatch(res)
			links = append(links, params[1])
		}
	})

	return links
}

func GetMovie(html io.Reader) (*Movie, error) {
	doc, err := goquery.NewDocumentFromReader(html)
	if err != nil {
		return nil, err
	}
	mv := &Movie{}
	mv.Name = doc.Find("#wrapper [property=\"v:itemreviewed\"]").Text()
	mv.Director = doc.Find("#wrapper [property=\"v:directedBy\"]").Text()
	mv.Starring = doc.Find("#wrapper #info .actor .attrs").Text()
	mv.Style = doc.Find("#wrapper [property=\"v:genre\"]").Text()
	// mv.Area = doc.Find("#info > span:nth-child(14)").Next().Text()
	mv.ReleaseDate = doc.Find("#wrapper [property=\"v:initialReleaseDate\"]").Text()
	mv.Len = doc.Find("#wrapper [property=\"v:runtime\"]").Text()
	mv.Description = doc.Find("#wrapper [property=\"v:summary\"]").Text()
	mv.Score = doc.Find("#wrapper [property=\"v:average\"]").Text()
	mv.EvaluateNums = doc.Find("#wrapper [property=\"v:votes\"]").Text()
	return mv, nil
}

func (mv *Movie) ToInsertSql() string {
	s := reflect.TypeOf(mv).Elem()
	v := reflect.ValueOf(mv).Elem()
	keys := []string{}
	values := []string{}
	for i := 0; i < s.NumField(); i++ {
		keys = append(keys, s.Field(i).Tag.Get("sql"))
		values = append(values, "'"+v.Field(i).String()+"'")
	}
	return fmt.Sprintf("insert into movie(%s) values(%s)", strings.Join(keys, ","), strings.Join(values, ","))
}

func init() {
	fmt.Println("movie init")
}
